package com.dog.basics.service.common.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dog.basics.bean.dto.admin.common.UserAddDto;
import com.dog.basics.bean.dto.admin.common.UserConnectAddDto;
import com.dog.basics.bean.dto.admin.common.UserEditDto;
import com.dog.basics.bean.dto.admin.common.UserFromDto;
import com.dog.basics.bean.dto.api.common.*;
import com.dog.basics.bean.model.common.DogUser;
import com.dog.basics.bean.model.common.DogUserChangeMobile;
import com.dog.basics.bean.vo.admin.common.MiniUserInfoUUidVo;
import com.dog.basics.bean.vo.admin.common.PcAllUserPageVo;
import com.dog.basics.bean.vo.admin.common.PcUserPageVo;
import com.dog.basics.bean.vo.api.common.ApiUserEditDto;
import com.dog.basics.common.constant.CommonConstants;
import com.dog.basics.common.util.HttpContextUtils;
import com.dog.basics.common.util.IpKit;
import com.dog.basics.common.util.PageParam;
import com.dog.basics.common.util.RedisUtil;
import com.dog.basics.dao.common.DogUserChangeMobileMapper;
import com.dog.basics.dao.common.DogUserMapper;
import com.dog.basics.security.util.SecurityUtils;
import com.dog.basics.service.common.IDogEmialService;
import com.dog.basics.service.common.IDogUserConnectService;
import com.dog.basics.service.common.IDogUserService;
import com.dog.basics.service.sys.MobileService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import ma.glasnost.orika.MapperFacade;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.net.URLEncoder;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author guoy
 * @since 2020-03-23
 */
@Service
@AllArgsConstructor
public class UserServiceImpl extends ServiceImpl<DogUserMapper, DogUser> implements IDogUserService {
    private final MobileService mobileService;
    private final IDogEmialService dogEmialService;
    private final DogUserChangeMobileMapper dogUserChangeMobileMapper;
    private final PasswordEncoder passwordEncoder;
    private final IDogUserConnectService dogUserConnectService;
    private final MapperFacade mapperFacade;
    private final WxMaService wxMaService;
    private final WxMaService wxMaTwoService;

    /**
     * @Description: 分页APP用户列表(pc)
     * @Param: name
     * @return: IPage<CompanyPageVo>
     * @Author: wph
     * @Date: 2020/3/27 0027
     */
    @Override
    public IPage<PcUserPageVo> getPageList(PageParam page, UserFromDto obj) {
        this.page(page, new LambdaQueryWrapper<DogUser>()
                .like(StrUtil.isNotBlank(obj.getNickName()), DogUser::getNickName, obj.getNickName())
                .like(StrUtil.isNotBlank(obj.getRealName()), DogUser::getRealName, obj.getRealName())
                .like(StrUtil.isNotBlank(obj.getUserMail()), DogUser::getUserMail, obj.getUserMail())
                .like(StrUtil.isNotBlank(obj.getUserMobile()), DogUser::getUserMobile, obj.getUserMobile())
                .eq(StrUtil.isNotBlank(obj.getSex()), DogUser::getSex, obj.getSex())
                .eq(ObjectUtil.isNotNull(obj.getNewsRemind()), DogUser::getNewsRemind, obj.getNewsRemind())
                .eq(ObjectUtil.isNotNull(obj.getLockFlag()), DogUser::getLockFlag, obj.getLockFlag())
                .orderBy(Boolean.TRUE, obj.getIsOrderByAvg(), DogUser::getUserRegtime));
        List<DogUser> records = page.getRecords();
        page.setRecords(records.stream().map(dogUser -> {
            PcUserPageVo pcUserPageVo = new PcUserPageVo();
            BeanUtil.copyProperties(dogUser, pcUserPageVo);
            return pcUserPageVo;
        }).collect(Collectors.toList()));
        return page;
    }

    /**
     * @Description: 全部用户列表
     * @Param: status
     * @return: IPage<CompanyPageVo>
     * @Author: wph
     * @Date: 2020/3/27 0027
     */
    @Override
    public List<PcAllUserPageVo> getAllPageList() {
        List<DogUser> oldList = this.list(Wrappers.<DogUser>lambdaQuery().eq(DogUser::getLockFlag, 0).orderByDesc(DogUser::getUserRegtime));
        List<PcAllUserPageVo> list = mapperFacade.mapAsList(oldList, PcAllUserPageVo.class);
        return list;
    }

    /**
     * 手机号注册 发送验证码
     *
     * @param phone
     * @return guonh 2019年12月21日
     */
    @Override
    public Boolean sendRegisterSms(String phone) {
        Validator.validateTrue(Validator.isMobile(phone), "请输入正确的手机号");
        List<DogUser> userList = this.list(Wrappers.<DogUser>lambdaQuery().eq(DogUser::getUserMobile, phone));
        Validator.validateTrue(CollUtil.isEmpty(userList), "用户已存在!");
        return mobileService.sendRegisterSms(phone);
    }

    /**
     * 手机号登陆 发送验证码
     *
     * @param phone
     * @return guonh 2019年12月21日
     */
    @Override
    public Boolean sendPhoneSms(String phone) {
        Validator.validateTrue(Validator.isMobile(phone), "请输入正确的手机号");
        // DogUser user = this.getOne(new LambdaQueryWrapper<DogUser>().eq(DogUser::getUserMobile, phone));
        //Validator.validateTrue(ObjectUtil.isNotNull(user), "用户不存在");
        return mobileService.sendPhoneSms(phone, -1L);
    }

    /**
     * 忘记密码登陆 发送验证码
     *
     * @param phone
     * @return guonh 2019年12月21日
     */
    @Override
    public Boolean sendforgetSms(String phone) {
        Validator.validateTrue(Validator.isMobile(phone), "请输入正确的手机号");
        DogUser user = this.getOne(new LambdaQueryWrapper<DogUser>().eq(DogUser::getUserMobile, phone));
        Validator.validateTrue(ObjectUtil.isNotNull(user), "用户不存在");
        return mobileService.sendforgetSms(phone, user.getUserId());
    }

    /**
     * 绑定手机号 发送验证码
     *
     * @param phone
     * @return guonh 2019年12月21日
     */
    @Override
    public Boolean sendBdSms(String phone) {
        Validator.validateTrue(Validator.isMobile(phone), "请输入正确的手机号");
        DogUser user = this.getOne(new LambdaQueryWrapper<DogUser>().eq(DogUser::getUserMobile, phone));
        Validator.validateTrue(ObjectUtil.isNotNull(user), "用户不存在");
        return mobileService.sendBdSms(phone, user.getUserId());
    }

    /**
     * 修改手机号 发送验证码
     *
     * @param phone
     * @return guonh 2019年12月21日
     */
    @Override
    public Boolean editPhoneSms(String phone) {
        Validator.validateTrue(Validator.isMobile(phone), "请输入正确的手机号");
        DogUser user = this.getOne(new LambdaQueryWrapper<DogUser>().eq(DogUser::getUserMobile, phone));
        Validator.validateFalse(ObjectUtil.isNotNull(user), "该手机号用户已经存在");
        return mobileService.sendSmsCode(phone, SecurityUtils.getUser().getUserId());
    }

    /**
     * 修改邮箱 发送验证码
     *
     * @param email
     * @return guonh 2019年12月21日
     */
    @Override
    public Boolean editEmailSms(String email) {
        Validator.validateTrue(Validator.isMobile(email), "请输入正确的手机号");
        List<DogUser> userList = this.list(Wrappers.<DogUser>lambdaQuery().eq(DogUser::getUserMail, email));
        Validator.validateTrue(CollUtil.isEmpty(userList), "用户已存在!");
        //生成验证码
        String captcha = RandomUtil.randomNumbers(4);
        return dogEmialService.sendEditSimpleMail(email, "修改邮箱验证码", captcha);
    }

    /**
     * 注册
     *
     * @param userRegisterDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean register(UserRegisterDto userRegisterDto) {
        DogUser olduser = this.getOne(new LambdaQueryWrapper<DogUser>().eq(DogUser::getUserMobile, userRegisterDto.getUserMobile()));
        Validator.validateTrue(Validator.isMobile(userRegisterDto.getUserMobile()), "请输入正确的手机号");
        Validator.validateTrue(ObjectUtil.isNull(olduser), "该手机号已经被注册!");
        Object redisCode = RedisUtil.get(CommonConstants.DEFAULT_CODE_KEY + "REGISTE@" + userRegisterDto.getUserMobile());
        // 判断用户验证码信息
        Validator.validateTrue(ObjectUtils.isNotNull(redisCode), "验证码过期或未发送!");
        Validator.validateEqual(userRegisterDto.getCode(), redisCode.toString(), "验证码不正确!");

        RedisUtil.del(CommonConstants.DEFAULT_CODE_KEY + "REGISTE@" + userRegisterDto.getUserMobile());
        //新密码
        String password = passwordEncoder.encode(userRegisterDto.getLoginPassword());
        //注册
        userRegisterDto.setLoginPassword(password);
        DogUser user = new DogUser();
        BeanUtil.copyProperties(userRegisterDto, user);
        user.setUserRegtime(DateUtil.currentSeconds());
        return this.save(user);


    }

    public Boolean saveEmialObj(UserRegisterDto userRegisterDto) {
        DogUser olduser = this.getOne(Wrappers.<DogUser>lambdaQuery().eq(DogUser::getUserMail, userRegisterDto.getUserMobile()));
        Validator.validateNull(olduser, "此用户已存在!");
        Object redisCode = RedisUtil.get(CommonConstants.EMAIL_DEFAULT_CODE_KEY + "REGISTE@" + userRegisterDto.getUserMobile());
        // 判断用户验证码信息
        Validator.validateTrue(ObjectUtils.isNotNull(redisCode), "验证码过期或未发送!");
        Validator.validateEqual(userRegisterDto.getCode(), redisCode.toString(), "验证码不正确!");
        RedisUtil.del(CommonConstants.EMAIL_DEFAULT_CODE_KEY + "REGISTE@" + userRegisterDto.getUserMobile());
        //新密码
        String password = passwordEncoder.encode(userRegisterDto.getLoginPassword());
        // 添加用户信息
        DogUser user = new DogUser();
        BeanUtil.copyProperties(userRegisterDto, user);
        user.setUserRegtime(DateUtil.currentSeconds());
        user.setLoginPassword(password);
        return this.save(user);
    }

    /**
     * 用户注册(手机号或者email)
     *
     * @param userRegisterDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean registerOrEmail(UserRegisterDto userRegisterDto) {
        //先判断手机号
        Boolean mobileFlage = Validator.isMobile(userRegisterDto.getUserMobile());
        //如果true就是手机号注册
        if (mobileFlage) {
            return this.register(userRegisterDto);
        } else {
            //如果是false 判断邮箱是否正确
            Validator.validateTrue(Validator.isEmail(userRegisterDto.getUserMobile()), "请输入正确的邮箱号或者手机号!");
            //邮箱正确开始邮箱注册
            return this.saveEmialObj(userRegisterDto);
        }
    }

    /**
     * 修改手机号
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateMobile(UpdateMobileDto dto) {
        // 校验手机号
        Validator.validateMobile(dto.getPhone(), "手机号格式错误");
        // 查询用户
        DogUser user = this.getById(SecurityUtils.getUser().getUserId());
        Object redisCode = RedisUtil.get(CommonConstants.DEFAULT_CODE_KEY + "EDIT@" + dto.getPhone());
        // 判断用户验证码信息
        Validator.validateTrue(ObjectUtils.isNotNull(redisCode), "验证码过期或未发送!");
        Validator.validateEqual(dto.getCode(), redisCode.toString(), "验证码不正确!");
        RedisUtil.del(CommonConstants.DEFAULT_CODE_KEY + "EDIT@" + dto.getPhone());
        //增加修改记录
        DogUserChangeMobile dogUserChangeMobile = new DogUserChangeMobile();
        dogUserChangeMobile.setUserId(SecurityUtils.getUser().getUserId());
        dogUserChangeMobile.setOldMobile(user.getUserMobile());
        dogUserChangeMobile.setNewMobile(dto.getPhone());
        dogUserChangeMobile.setCreateTime(DateUtil.currentSeconds());
        dogUserChangeMobile.setCreateBy(SecurityUtils.getUser().getUserId());
        Validator.validateTrue(retBool(dogUserChangeMobileMapper.insert(dogUserChangeMobile)), "保存手机变动信息失败!");
        user.setUserMobile(dto.getPhone());
        user.setModifyTime(DateUtil.currentSeconds());
        return this.updateById(user);

    }


    /**
     * 修改邮箱
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateEmail(UpdateEmailDto dto) {
        // 校验邮箱
        Validator.validateEmail(dto.getEmail(), "邮箱号格式错误");
        // 查询用户
        DogUser user = this.getById(SecurityUtils.getUser().getUserId());
        Object redisCode = RedisUtil.get(CommonConstants.EMAIL_DEFAULT_CODE_KEY + "EDIT@" + dto.getEmail());
        // 判断用户验证码信息
        Validator.validateTrue(ObjectUtils.isNotNull(redisCode), "验证码过期或未发送!");
        Validator.validateEqual(dto.getCode(), redisCode.toString(), "验证码不正确!");
        RedisUtil.del(CommonConstants.EMAIL_DEFAULT_CODE_KEY + "EDIT@" + dto.getEmail());
        //增加修改记录
        DogUserChangeMobile dogUserChangeMobile = new DogUserChangeMobile();
        dogUserChangeMobile.setUserId(SecurityUtils.getUser().getUserId());
        dogUserChangeMobile.setOldMobile(user.getUserMobile());
        dogUserChangeMobile.setNewMobile(dto.getEmail());
        dogUserChangeMobile.setCreateTime(DateUtil.currentSeconds());
        dogUserChangeMobile.setCreateBy(SecurityUtils.getUser().getUserId());
        dogUserChangeMobile.setType(1);
        Validator.validateTrue(retBool(dogUserChangeMobileMapper.insert(dogUserChangeMobile)), "保存邮箱变动信息失败!");
        user.setUserMail(dto.getEmail());
        user.setModifyTime(DateUtil.currentSeconds());
        return this.updateById(user);

    }

    /**
     * Api修改用户信息
     *
     * @param obj
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editInfo(ApiUserEditDto obj) {
        DogUser user = BeanUtil.copyProperties(obj, DogUser.class);
        user.setUserId(SecurityUtils.getUser().getUserId());
        user.setModifyTime(DateUtil.currentSeconds());
        return this.updateById(user);
    }

    /**
     * @Description: 启用冻结用户
     * @Param: Boolean
     * @return: Boolean
     * @Author: wph
     * @Date: 2020/4/9  0027
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean nouse(Long id) {
        DogUser dogDoctor = this.getById(id);
        Validator.validateNotNull(dogDoctor, "无此数据");
        dogDoctor.setLockFlag(dogDoctor.getLockFlag() == 0 ? 9 : 0);
        return this.updateById(dogDoctor);
    }

    /**
     * @Description: 重置密码
     * @Param: Boolean
     * @return: Boolean
     * @Author: wph
     * @Date: 2020/4/9  0027
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editResetPassword(Long id) {
        DogUser dogDoctor = this.getById(id);
        Validator.validateNotNull(dogDoctor, "无此数据");
        dogDoctor.setLoginPassword(passwordEncoder.encode("123456"));
        return this.updateById(dogDoctor);
    }

    /**
     * @Description: 开启关闭消息提醒
     * @Param: Boolean
     * @return: Boolean
     * @Author: wph
     * @Date: 2020/4/9  0027
     */
    @Override
    public Boolean userMessage(Long id) {
        DogUser dogDoctor = this.getById(id);
        Validator.validateNotNull(dogDoctor, "无此数据");
        dogDoctor.setNewsRemind(dogDoctor.getNewsRemind() == 0 ? 1 : 0);
        return this.updateById(dogDoctor);
    }


    /***
     * 添加用户信息 - (系统)
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addUser(UserAddDto dto) {
        // 判断用户手机号是否正规
        Validator.validateMobile(dto.getUserMobile(), "手机号不合法");
        // 判断数据库手机号是否还有
        List<DogUser> users = this.list(Wrappers.<DogUser>lambdaQuery().eq(DogUser::getUserMobile, dto.getUserMobile()));
        Validator.validateTrue(CollUtil.isEmpty(users), "输入账户账号,已存在,请换登陆账户");
        // 数据信息转义
        DogUser user = BeanUtil.toBean(dto, DogUser.class);
        user.setUserRegtime(DateUtil.currentSeconds());
        user.setUserRegip(IpKit.getRealIp(HttpContextUtils.getHttpServletRequest()));
        Validator.validateTrue(this.save(user), "添加用户信息失败");
        return Boolean.TRUE;
    }


    /***
     * 修改用户信息 - (系统)
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editUser(UserEditDto dto) {
        // 查询用户信息是否存
        DogUser userByid = this.getById(dto.getUserId());
        Validator.validateNotNull(userByid, "用户信息不存在");

        // 判断是否修改手机号码
        if (!Validator.equal(userByid.getUserMobile(), dto.getUserMobile())) {
            // 判断用户手机号是否正规
            Validator.validateMobile(dto.getUserMobile(), "手机号不合法");
            // 判断数据库手机号是否还有
            List<DogUser> users = this.list(Wrappers.<DogUser>lambdaQuery().eq(DogUser::getUserMobile, dto.getUserMobile()));
            Validator.validateTrue(CollUtil.isEmpty(users), "输入账户账号,已存在,请换登陆账户");
        }
        // 数据信息转义
        DogUser user = BeanUtil.toBean(dto, DogUser.class);
        user.setModifyTime(DateUtil.currentSeconds());
        Validator.validateTrue(this.updateById(user), "修改用户信息失败");
        return Boolean.TRUE;
    }


    /**
     * 修改密码和忘记密码
     *
     * @param userRegisterDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean forgetPassword(UserRegisterDto userRegisterDto) {
        //先判断手机号
        Boolean mobileFlage = Validator.isMobile(userRegisterDto.getUserMobile());
        //如果true就是手机号注册
        if (mobileFlage) {
            List<DogUser> userList = this.list(new LambdaQueryWrapper<DogUser>().eq(DogUser::getUserMobile, userRegisterDto.getUserMobile()));
            Validator.validateTrue(CollUtil.isNotEmpty(userList), "用户不存在");
            Object redisCode = RedisUtil.get(CommonConstants.DEFAULT_CODE_KEY + "FORGET@" + userRegisterDto.getUserMobile());
            // 判断用户验证码信息
            Validator.validateTrue(ObjectUtils.isNotNull(redisCode), "验证码过期或未发送!");
            Validator.validateEqual(userRegisterDto.getCode(), redisCode.toString(), "验证码不正确!");
            RedisUtil.del(CommonConstants.DEFAULT_CODE_KEY + "FORGET@" + userRegisterDto.getUserMobile());
            //新密码
            String newPassword = passwordEncoder.encode(userRegisterDto.getLoginPassword());
            //更新密码
            DogUser user = userList.get(0);
            user.setLoginPassword(newPassword);
            return this.updateById(user);

        } else {
            //如果是false 判断邮箱是否正确
            Validator.validateTrue(Validator.isEmail(userRegisterDto.getUserMobile()), "请输入正确的邮箱号或者手机号!");
            List<DogUser> userList = this.list(new LambdaQueryWrapper<DogUser>().eq(DogUser::getUserMail, userRegisterDto.getUserMobile()));
            Validator.validateTrue(CollUtil.isNotEmpty(userList), "用户不存在!");
            Object redisCode = RedisUtil.get(CommonConstants.EMAIL_DEFAULT_CODE_KEY + "EDIT@" + userRegisterDto.getUserMobile());
            // 判断用户验证码信息
            Validator.validateTrue(ObjectUtils.isNotNull(redisCode), "验证码过期或未发送!");
            Validator.validateEqual(userRegisterDto.getCode(), redisCode.toString(), "验证码不正确!");
            RedisUtil.del(CommonConstants.EMAIL_DEFAULT_CODE_KEY + "EDIT@" + userRegisterDto.getUserMobile());
            //新密码
            String newPassword = passwordEncoder.encode(userRegisterDto.getLoginPassword());
            //更新密码
            DogUser user = userList.get(0);
            user.setLoginPassword(newPassword);
            return this.updateById(user);
        }
    }

    /**
     * 修改密码
     *
     * @param passwordDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editPassword(PasswordDto passwordDto) {
        DogUser user = this.getById(SecurityUtils.getUser().getUserId());
        Validator.validateTrue(passwordEncoder.matches(passwordDto.getOldPassword(), user.getLoginPassword()), "输入的原密码不正确!");
        Validator.validateTrue(Validator.isBetween(passwordDto.getPassword().length(), 6, 12), "密码应为6到12位!");
        //新密码
        String newPassword = passwordEncoder.encode(passwordDto.getPassword());
        //更新密码
        user.setLoginPassword(newPassword);
        return this.updateById(user);
    }

    /**
     * @Description: 修改支付密码
     * @Param: oldpassword, password
     * @return: Boolean
     * @Author: wph
     * @Date: 2020/3/27 0027
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean editPayPassword(PayPasswordDto obj) {
        DogUser user = this.getById(SecurityUtils.getUser().getUserId());
        Validator.validateTrue(Validator.isBetween(obj.getPassword().length(), 6, 12), "密码应为6到12位!");
        //更新密码
        user.setPayPassword(obj.getPassword());
        Validator.validateTrue(this.updateById(user), "修改失败!");
        return Boolean.TRUE;
    }

    /**
     * 绑定
     *
     * @param bdUserDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean bdUser(BdUserDto bdUserDto) {
        DogUser dogUser = new DogUser();
        //先判断手机号
        Boolean mobileFlage = Validator.isMobile(bdUserDto.getPhone());
        //如果true就是手机号注册
        if (mobileFlage) {
            List<DogUser> userList = this.list(new LambdaQueryWrapper<DogUser>().eq(DogUser::getUserMobile, bdUserDto.getPhone()));
            Validator.validateTrue(CollUtil.isNotEmpty(userList), "用户不存在!");
            Object redisCode = RedisUtil.get(CommonConstants.DEFAULT_CODE_KEY + "BD@" + bdUserDto.getPhone());
            // 判断用户验证码信息
            Validator.validateTrue(ObjectUtils.isNotNull(redisCode), "验证码过期或未发送!");
            Validator.validateEqual(bdUserDto.getCode(), redisCode.toString(), "验证码不正确!");
            RedisUtil.del(CommonConstants.DEFAULT_CODE_KEY + "BD@" + bdUserDto.getPhone());
            userList.get(0);
            BeanUtil.copyProperties(userList.get(0), dogUser);
        } else {
            //如果是false 判断邮箱是否正确
            Validator.validateTrue(Validator.isEmail(bdUserDto.getPhone()), "请输入正确的邮箱号或者手机号!");
            List<DogUser> userList = this.list(new LambdaQueryWrapper<DogUser>().eq(DogUser::getUserMail, bdUserDto.getPhone()));
            Validator.validateTrue(CollUtil.isNotEmpty(userList), "用户不存在!");
            Object redisCode = RedisUtil.get(CommonConstants.EMAIL_DEFAULT_CODE_KEY + "@" + bdUserDto.getPhone());
            // 判断用户验证码信息
            Validator.validateTrue(ObjectUtils.isNotNull(redisCode), "验证码过期或未发送!");
            Validator.validateEqual(bdUserDto.getCode(), redisCode.toString(), "验证码不正确!");
            RedisUtil.del(CommonConstants.EMAIL_DEFAULT_CODE_KEY + "@" + bdUserDto.getPhone());
            userList.get(0);
            BeanUtil.copyProperties(userList.get(0), dogUser);
        }
        //新增第三方信息
        UserConnectAddDto userConnectAddDto = new UserConnectAddDto();
        userConnectAddDto.setUserId(dogUser.getUserId());
        if (bdUserDto.getType() == 0) {
            userConnectAddDto.setGzhOpenid(bdUserDto.getOpenid());
        } else if (bdUserDto.getType() == 1) {
            userConnectAddDto.setMiniOpenid(bdUserDto.getOpenid());
        } else {
            userConnectAddDto.setAppOpenid(bdUserDto.getOpenid());
        }
        return dogUserConnectService.saveObj(userConnectAddDto);
    }


    /**
     * 获取微信手机号 （小程序）
     *
     * @param dto
     * @return guonh 2020年3月6日
     */
    @Override
    @SneakyThrows
    public Boolean getWxPhone(WxPhoneDto dto) {
        // 判断是否为空
        Validator.validateTrue(StrUtil.isNotBlank(dto.getCode()), "Code不能为空");
        Validator.validateTrue(StrUtil.isNotBlank(dto.getEncryptedData()), "EncryptedData不能为空");
        Validator.validateTrue(StrUtil.isNotBlank(dto.getIvStr()), "IvStr不能为空");
        // 获取 SessionKey
        WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(dto.getCode());
        // 判断是否正确内容
        //Validator.validateTrue(wxMaService.getUserService().checkUserInfo(sessionInfo.getSessionKey(), dto.getRawData(), dto.getSignature()), "校验有异");
        // 获取手机号
        //String encryptedData = dto.getEncryptedData().replace(" ", "+");
        String ivStr = URLEncoder.encode(dto.getIvStr(), "UTF-8").replace("%3D", "=").replace("%2F", "/");
        String encryptedData = URLEncoder.encode(dto.getEncryptedData(), "UTF-8").replace("%3D", "=").replace("%2F", "/");
        // WxMaUserInfo wxMaUserInfo = wxMaService.getUserService().getUserInfo(sessionInfo.getSessionKey(), encryptedData, dto.getIvStr());
        WxMaPhoneNumberInfo phoneNoInfo = wxMaService.getUserService().getPhoneNoInfo(sessionInfo.getSessionKey(), encryptedData, ivStr);
        Validator.validateTrue((StrUtil.isNotBlank(phoneNoInfo.getPhoneNumber())), "授权获取不到您的手机号(请检阅是否微信是否绑定手机号谢谢)");
        //绑定用户
        DogUser dogUser = this.getById(SecurityUtils.getUser().getUserId());
        Validator.validateNotNull(dogUser, "用户不存在");
        dogUser.setUserMobile(phoneNoInfo.getPhoneNumber());
        Validator.validateTrue(this.updateById(dogUser), "绑定手机号失败!");
        return Boolean.TRUE;
    }

    /**
     * 获取商城微信手机号
     *
     * @param dto
     * @return guonh 2020年3月6日
     */
    @Override
    @SneakyThrows
    public Boolean wxShopPhone(WxPhoneDto dto) {
        // 判断是否为空
        Validator.validateTrue(StrUtil.isNotBlank(dto.getCode()), "Code不能为空");
        Validator.validateTrue(StrUtil.isNotBlank(dto.getEncryptedData()), "EncryptedData不能为空");
        Validator.validateTrue(StrUtil.isNotBlank(dto.getIvStr()), "IvStr不能为空");
        // 获取 SessionKey
        WxMaJscode2SessionResult sessionInfo = wxMaTwoService.getUserService().getSessionInfo(dto.getCode());
        // 判断是否正确内容
        //Validator.validateTrue(wxMaService.getUserService().checkUserInfo(sessionInfo.getSessionKey(), dto.getRawData(), dto.getSignature()), "校验有异");
        // 获取手机号
        //  String encryptedData = dto.getEncryptedData().replace(" ", "+");
        String ivStr = URLEncoder.encode(dto.getIvStr(), "UTF-8").replace("%3D", "=").replace("%2F", "/");
        String encryptedData = URLEncoder.encode(dto.getEncryptedData(), "UTF-8").replace("%3D", "=").replace("%2F", "/");
        // WxMaUserInfo wxMaUserInfo = wxMaTwoService.getUserService().getUserInfo(sessionInfo.getSessionKey(), encryptedData, dto.getIvStr());
        WxMaPhoneNumberInfo phoneNoInfo = wxMaTwoService.getUserService().getPhoneNoInfo(sessionInfo.getSessionKey(), encryptedData, ivStr);
        Validator.validateTrue((StrUtil.isNotBlank(phoneNoInfo.getPhoneNumber())), "授权获取不到您的手机号(请检阅是否微信是否绑定手机号谢谢)");
        //绑定用户
        DogUser dogUser = this.getById(SecurityUtils.getUser().getUserId());
        Validator.validateNotNull(dogUser, "用户不存在");
        dogUser.setUserMobile(phoneNoInfo.getPhoneNumber());
        Validator.validateTrue(this.updateById(dogUser), "绑定手机号失败!");
        return Boolean.TRUE;
    }

    /**
     * 获取微信手机号 （小程序）
     *
     * @param dto
     * @return guonh 2020年3月6日
     */
 /*     @Override
    @SneakyThrows
  public Boolean gewxUuId(WxPhoneDto dto) {
        // 判断是否为空
        Validator.validateTrue(StrUtil.isNotBlank(dto.getCode()), "Code不能为空");
        // 获取 SessionKey
        WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(dto.getCode());
        // 获取手机号
        String encryptedData = dto.getEncryptedData().replace(" ", "+");
        WxMaUserInfo wxMaUserInfo = wxMaService.getUserService().getUserInfo(sessionInfo.getSessionKey(), encryptedData, dto.getIvStr());
        String unionid = wxMaUserInfo.getUnionId();
        Validator.validateTrue(StrUtil.isNotBlank(unionid), "微信授权失败!");
        //先查询这个openId存在吗 存在了删除
        List<Long> openIdList = dogUserConnectService.list(Wrappers.<DogUserConnect>lambdaQuery().eq(DogUserConnect::getMiniOpenid, unionid).orderByDesc(DogUserConnect::getCreateTime)).stream().map(e -> e.getId()).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(openIdList)) {
            Validator.validateTrue(dogUserConnectService.removeByIds(openIdList), "绑定失败!");
        }
        List<DogUserConnect> list = dogUserConnectService.list(Wrappers.<DogUserConnect>lambdaQuery().eq(DogUserConnect::getUserId, SecurityUtils.getUser().getUserId()).orderByDesc(DogUserConnect::getCreateTime));
        if (CollUtil.isNotEmpty(list)) {
            DogUserConnect newObj = list.get(0);
            newObj.setMiniOpenid(unionid);
            newObj.setUpdateTime(DateUtil.currentSeconds());
            newObj.setUpdateBy(SecurityUtils.getUser().getUserId());
            Validator.validateTrue(dogUserConnectService.updateById(newObj), "绑定失败!");
        } else {
            DogUserConnect newObj = new DogUserConnect();
            newObj.setUserId(SecurityUtils.getUser().getUserId());
            newObj.setMiniOpenid(unionid);
            newObj.setCreateTime(DateUtil.currentSeconds());
            newObj.setCreateBy(SecurityUtils.getUser().getUserId());
            Validator.validateTrue(dogUserConnectService.save(newObj), "绑定失败!");

        }
        return Boolean.TRUE;
    }*/


    /**
     * 获取微信uuid
     *
     * @param dto
     * @return guonh 2020年3月6日
     */
    @Override
    @SneakyThrows
    public MiniUserInfoUUidVo gewxUuId(WxPhoneDto dto) {
        MiniUserInfoUUidVo miniUserInfoUUidVo = new MiniUserInfoUUidVo();
        // 判断是否为空
        Validator.validateTrue(StrUtil.isNotBlank(dto.getCode()), "Code不能为空");
        Validator.validateTrue(StrUtil.isNotBlank(dto.getEncryptedData()), "EncryptedData不能为空");
        Validator.validateTrue(StrUtil.isNotBlank(dto.getIvStr()), "IvStr不能为空");
        // 获取 SessionKey
        WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(dto.getCode());
        // 获取手机号
        String ivStr = URLEncoder.encode(dto.getIvStr(), "UTF-8").replace("%3D", "=").replace("%2F", "/");
        String encryptedData = URLEncoder.encode(dto.getEncryptedData(), "UTF-8").replace("%3D", "=").replace("%2F", "/");
        WxMaUserInfo wxMaUserInfo = wxMaService.getUserService().getUserInfo(sessionInfo.getSessionKey(), encryptedData, ivStr);
        miniUserInfoUUidVo.setOpenId(wxMaUserInfo.getOpenId());
        miniUserInfoUUidVo.setUnionId(wxMaUserInfo.getUnionId());

        return miniUserInfoUUidVo;
    }

    /**
     * 获取微信uuid 商城
     *
     * @param dto
     * @return guonh 2020年3月6日
     */
    @Override
    @SneakyThrows
    public MiniUserInfoUUidVo gewxShopUuId(WxPhoneDto dto) {
        MiniUserInfoUUidVo miniUserInfoUUidVo = new MiniUserInfoUUidVo();
        // 判断是否为空
        Validator.validateTrue(StrUtil.isNotBlank(dto.getCode()), "Code不能为空");
        Validator.validateTrue(StrUtil.isNotBlank(dto.getEncryptedData()), "EncryptedData不能为空");
        Validator.validateTrue(StrUtil.isNotBlank(dto.getIvStr()), "IvStr不能为空");

        // 获取 SessionKey
        WxMaJscode2SessionResult sessionInfo = wxMaTwoService.getUserService().getSessionInfo(dto.getCode());
        // 获取手机号
        String ivStr = URLEncoder.encode(dto.getIvStr(), "UTF-8").replace("%3D", "=").replace("%2F", "/");
        String encryptedData = URLEncoder.encode(dto.getEncryptedData(), "UTF-8").replace("%3D", "=").replace("%2F", "/");
        WxMaUserInfo wxMaUserInfo = wxMaTwoService.getUserService().getUserInfo(sessionInfo.getSessionKey(), encryptedData, ivStr);
        miniUserInfoUUidVo.setOpenId(wxMaUserInfo.getOpenId());
        miniUserInfoUUidVo.setUnionId(wxMaUserInfo.getUnionId());
        return miniUserInfoUUidVo;
    }


}

